#ifndef ASAN_SHADOW_MEMORY
#define ASAN_SHADOW_MEMORY
#include "asan_internal_defs.h"
#include "asan_mapping.h"


#define SHADOW_UNIT_TYPE char

namespace __sanitizer {

typedef SHADOW_UNIT_TYPE su_t;

u64 MmapFixed(uptr fixed_addr, uptr size, int additional_flags, const char* name);

struct AsanShadowMem {
  fd_t high_mmap_fd;
  fd_t mid_mmap_fd;
  fd_t low_mmap_fd;
  int scale;
  int scale_factor;
  int half_scale_factor;
  uptr beg;
  uptr end;
  u64 size;

  int InitShadow();
  int DeleteShadow();
  int PoisonMem(const void* membeg, uptr size, su_t v);
  int UnpoisonMem(const void* membeg, uptr size);
  bool IsPoisonedMem(const void* membeg, uptr size);
  bool IsFreeAfterUse(const void* membeg);
  uptr GetPoisonedAddr(const void* membeg, uptr size);

  su_t PoisonUnitHeadBytes(su_t old_value, su_t new_value, int affected_bytes);
  su_t PoisonUnitTailBytes(su_t old_value, su_t new_value, int affected_bytes);
  su_t PoisonUnit(su_t old_value, su_t new_value, int beg_byte, int end_byte);

  su_t UnpoisonUnitHeadBytes(su_t old_value, int affected_bytes);
  su_t UnpoisonUnitTailBytes(su_t old_value, int affected_bytes);
  su_t UnpoisonUnit(su_t old_value, int beg_byte, int end_byte);

  bool IsPoisonedUnit(su_t old_value, int beg_byte, int end_byte);
};

} // namespace __sanitizer


#endif // ASAN_SHADOW_MEMORY